- /* slfrdp2r.cpp by K.Tsuru */
- // function ID = 2007 DRADIX, BRADIX
- /*******************************************************************************
- SLong class
- If m and n have a common divisor in type 2^b*R^r, they are divided by it.
- The results is overwritten on m and n.
- divisor = NULL(default)
- If divisor != NULL the divisor is written on it.
- The type of *divisor is the same as m and n.
- It is used in SFraction::reduce(), etc.
- For the SLong value(radix=DRADIX) it seems to be better to divide by the power of
- five, but the probability of having a large common divisor 5^q is little because
- it is devided by the power of DRADIX.
- *********************************************************************************/
- #ifndef SN_H
- #include "sn.h"
- #endif
- void ReduceByPow2Rdx(SLong& m, SLong& n, SLong* divisor){
- if( (m[0] & 1) || (n[0] & 1) ){ // m or n is odd.
- if(divisor != NULL) *divisor = 1;
- return;
- }
- if( m.Sign()*n.Sign() == 0){ // m == 0 || n == 0
- if(divisor != NULL) *divisor = 1;
- return;
- }
- if(m.Type() != n.Type()) m.SetError(m.RADIX_ERR,"ReduceByPow2Rdx", 2007);
- int cdRdxPow = (int)min(m.Tail(), n.Tail());
- // power of common divisor R^r
- if(cdRdxPow){ //devide by R^cdRdxPow
- m.MultPowRdx(-cdRdxPow); n.MultPowRdx(-cdRdxPow);
- }
- //It devides by a common divisor 2^n.
- //See also DivPow2() in gcdL().
- ulong cdPow2 = 0; //power of common divisor 2^n
- if( !(m[0] % 2u) && !(n[0] % 2u) ){ //Both are even numbers.
- // 16 8
- uint pow2 = (m.Type() == m.BIN_INT) ? (8u*sizeof(ulong)-BRADIX_BITS -1u) : 2u*DFIGURES;
- /*
- For the SLong value in order to the initial value of 'pow2' to be 16, it is necessary
- to judge whether have a factor 2^16 or not. To do so it needs to test lowest four
- figures.
- */
- ulong div = 1uL << pow2;
- while(div >= 2uL){
- while( !(m.Low2() % div) && !(n.Low2() % div) ){
- // m /= 2^pow2; n /= 2^pow2;
- LDivPow2(m, m, pow2); LDivPow2(n, n, pow2);
- cdPow2 += pow2;
- }
- div /= 2uL; pow2--;
- }
- }
- if(divisor == NULL) return;
- #ifndef NDEBUG
- assert( (m[0] & 1) || (n[0] & 1) ); // m or n is odd.
- assert( cdPow2 || cdRdxPow ); //It must be divisor > 1.
- #endif
- if(cdPow2){
- SLong two(m.Type(), m.MinSize(), 2); // = 2
- *divisor = Lpow(two, cdPow2); // 2^cdPow2
- } else {
- *divisor = SLong(m.Type(), m.MinSize(), 1); // = 1
- }
-
- if(cdRdxPow) divisor->MultPowRdx(cdRdxPow); //It multiplies by R^cdRdxPow.
- }
slfrdp2r.cpp : last modifiled at 2015/11/27 14:06:12(2,474 bytes)
created at 2017/10/07 10:26:50
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).